package Market;


import java.util.*;

import edu.iastate.jrelm.rl.SimpleStatelessLearner;
import sim.engine.*;


public class Market extends SimState{
	
	private static final long serialVersionUID = 6628525522939315274L;
							
	   
	  public Hashtable<String, Object> lmpAtHour = new Hashtable<String, Object>() ;

	  											/** list of GenCos */
	  public Hashtable<String, GenCo> genCoList = new Hashtable<String, GenCo>() ;

	  public Hashtable<String, Object> branchList = new Hashtable<String, Object>() ;

	  											/** Twenty-four hours */
	  public final int Hours = 24;
	  											/** list of LSEs */
	  public Hashtable<String, LSE> lseList = new Hashtable<String, LSE>() ;
// ISO
	  											/** Local marginal price for each hour and node [Hour][Node] */
	  private double [][] LMP;
	  											/** Current day */  
	  public static int D;
	  public Hashtable<String, Object> reportedSupplyOffer = new Hashtable<String, Object>();
	  public Hashtable<String, Double> nodeData = new Hashtable<String, Double>() ;
//C-O-N-S-T-R-U-C-T-O-R------------------------------------------------------------------------------------------------------------------------------  


	    public Market(long seed)
	    {
	        super(seed);
	    }
	//-----------------------------------------------------------------
	    

	   public void start()
	   {
	        super.start();
	  
	     new Initials.InitGenCo(this);
      	 new Initials.InitLSE(this);
      	 new Initials.InitBranch(this);
      	 new Initials.InitNode(this);
      	ElGrid elgrid             = new ElGrid();
      	        	
      	GenCo gen  = null;
      	
      	for(int i=0; i<genCoList.size(); i++)
      	{
      		int id = i+1;      		     		
      		gen = genCoList.get("genco"+id);    		 		    		     		
      		this.schedule.scheduleRepeating(gen, 0, 1d);                   		
      	} 
      	
      	
      	
//----- LSE-------------------------------------------------     
      	LSE lse =null;
      	for(int j=0; j<lseList.size(); j++)
      	{
      		int id = j+1;
      		lse = lseList.get("lse"+id); 				
      		this.schedule.scheduleRepeating(lse, 1, 1d);	     		      		
      		elgrid.addLSEAtNodeK(lse, lse.node);                        	
      		}
//----- ISO-------------------------------------------------     	
      		ISO iso = new ISO(this);
      		this.schedule.scheduleRepeating(iso, 2, 1d);		
   
	 }      
//-------M-A-I-N---------------------------------------------------------------------------------------
     public static void main(String[] args){
          Market market = new Market(System.currentTimeMillis());       
          market.start();
          long jobsMax=5;
          int stepMax=365;
          for (int jobs=0; jobs<=jobsMax-1; jobs++)
  	      {
        	  System.out.println("======simulation======"+jobs);
        	//  market.start();
          	do
    		{
          		if (!market.schedule.step(market))
   			   {
   				   System.err.println("Error with the step function of the AWEM model");
   				   break;
   			   }
          		//end of step
          		market.makeGenCoLearn();
          	 	System.out.println("======days======"+market.schedule.getSteps());
          	  } 
    		  while (market.schedule.getSteps() < stepMax-1);
          	
  	      	}
                  
          System.out.println("Done!!!");
          market.finish();
          System.exit(0);
      }
   
    public void  makeGenCoLearn()
    {
    	GenCo gen  = null;
        Enumeration e = genCoList.keys();
      // if (e == null){return;}
        while(e.hasMoreElements())
        {
        	gen = genCoList.get(e.nextElement());
        	gen.learn();
        }		 
    }
         
    /** Sets LMP list for each hour and node */
    public void setLMPList(double[] lmp, int h )
    {    	 	
    	for (int i=0; i<nodeData.size(); i++)
    	{
    		LMP[h][i] = lmp[i];
    	}
    }
 
    /** Returns LMP */
    public double[][] getLMP()
    {
    	return LMP;	
    }

	
}
